from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, logout
from django.views.generic import CreateView, UpdateView
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

from allauth.account.views import SignupView, LoginView
from allauth.socialaccount.providers.oauth2.views import OAuth2Adapter
from .models import Product, Category, Order, OrderItem, UserProfile
from .serializers import UserSerializer, AddressSerializer, CategorySerializer, ProductSerializer
from django.contrib import messages


import redis
from django.db import transaction
from django.core.exceptions import ValidationError

import hashlib
import time
from import_export import resources
from celery import shared_task
from django_celery_beat.models import PeriodicTask




from django.db.models.signals import post_save
from django.dispatch import receiver


class AdminProductResource(resources.ModelResource):
    class Meta:
        model = Product
        fields = ('id', 'name', 'price', 'stock', 'category', 'created_at')






from django_fsm import FSMField, transition


@shared_task
def check_low_stock_products():
    """Celery定时任务检查低库存商品"""
    threshold = getattr(settings, 'LOW_STOCK_THRESHOLD', 10)
    low_stock = Product.objects.filter(stock__lt=threshold)
    
    for product in low_stock:
        product.is_active = False
        product.save()
        
        # 发送预警通知
        send_mail(
            f'商品{product.name}库存不足已下架',
            f'商品ID: {product.id}, 当前库存: {product.stock}',
            settings.DEFAULT_FROM_EMAIL,
            [settings.ADMIN_EMAIL]
        )


class OrderStatusMixin:
    @transition(field='status', source='unpaid', target='cancelled')
    def cancel(self):
        pass

    @transition(field='status', source='unpaid', target='paid')
    def pay(self):
        pass

    @transition(field='status', source='paid', target='shipped')
    def ship(self):
        pass














@receiver(post_save, sender=UserProfile)
def send_welcome_coupon(sender, instance, created, **kwargs):
    """新用户注册24小时内发送首单折扣券"""
    if created:
        Coupon.objects.create(
            user=instance.user,
            code=f'WELCOME{instance.user.id}',
            discount=20,
            valid_until=timezone.now()+timedelta(days=1)
        )








def product_list(request):
    categories = Category.objects.all()
    products = Product.objects.filter(stock__gt=0)
    
    return render(request, 'shop/product/list.html', {
        'categories': categories,
        'products': products,
    })


def product_detail(request, id, slug):
    product = get_object_or_404(Product, id=id, slug=slug)
    return render(request, 'shop/product/detail.html', {'product': product})


@login_required
@transaction.atomic
def order_create(request):
    if request.method == 'POST':
        cart_key = f'cart:{request.user.id}'
        redis_conn = redis.StrictRedis(host='localhost', port=6379, db=0)
        cart_items = redis_conn.hgetall(cart_key)
        
        try:
            # 生成唯一订单号
            order_no = f"{int(time.time())}{hash(request.user.id)}"
            
            # 创建订单
            order = Order.objects.create(
                user=request.user,
                order_no=order_no,
                status='unpaid'
            )
            
            # 处理每个购物车商品
            for product_id, quantity in cart_items.items():
                product = Product.objects.select_for_update().get(id=product_id)
                if product.stock < int(quantity):
                    raise ValidationError(f'{product.name}库存不足')
                
                # 创建订单项
                OrderItem.objects.create(
                    order=order,
                    product=product,
                    price=product.price,
                    quantity=quantity
                )
                
                # 扣减库存
                product.stock -= int(quantity)
                product.save()
            
            # 清空购物车
            redis_conn.delete(cart_key)
            
            return redirect('order-detail', order_id=order.id)
        except Exception as e:
            return render(request, 'shop/order/create.html', {'error': str(e)})
    
    return render(request, 'shop/order/create.html')


@login_required
def order_list(request):
    orders = Order.objects.filter(user=request.user)
    return render(request, 'shop/order/list.html', {'orders': orders})


@login_required
def order_detail(request, order_id):
    order = get_object_or_404(Order, id=order_id, user=request.user)
    return render(request, 'shop/order/detail.html', {'order': order})


class UserRegistrationView(SignupView):
    template_name = 'shop/auth/register.html'


class UserLoginView(LoginView):
    template_name = 'shop/auth/login.html'


class UserProfileView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        serializer = UserSerializer(request.user)
        return Response(serializer.data)


class AddressListView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        addresses = request.user.addresses.all()
        serializer = AddressSerializer(addresses, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = AddressSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CartView(APIView):
    permission_classes = [IsAuthenticated]
    
    def __init__(self):
        self.redis_conn = redis.StrictRedis(host='localhost', port=6379, db=0)
    
    def get(self, request):
        cart_key = f'cart:{request.user.id}'
        cart_items = self.redis_conn.hgetall(cart_key)
        return Response(cart_items)
    
    def post(self, request):
        product_id = request.data.get('product_id')
        quantity = int(request.data.get('quantity', 1))
        
        cart_key = f'cart:{request.user.id}'
        self.redis_conn.hincrby(cart_key, product_id, quantity)
        return Response({'status': 'success'})
    
    def delete(self, request):
        product_id = request.data.get('product_id')
        cart_key = f'cart:{request.user.id}'
        self.redis_conn.hdel(cart_key, product_id)
        return Response({'status': 'success'})


class StockReservationView(APIView):
    permission_classes = [IsAuthenticated]
    
    @transaction.atomic
    def post(self, request):
        product_id = request.data.get('product_id')
        quantity = int(request.data.get('quantity', 1))
        
        try:
            product = Product.objects.select_for_update().get(id=product_id)
            if product.stock < quantity:
                raise ValidationError('库存不足')
            
            product.stock -= quantity
            product.save()
            
            # 这里可以添加Saga事务的补偿逻辑
            return Response({'status': 'success'})
        except Product.DoesNotExist:
            return Response({'error': '商品不存在'}, status=status.HTTP_404_NOT_FOUND)
        except ValidationError as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
